<template>
  <div ref="root" :class="['scrollbar__bar', 'is-' + bar.key]" @mousedown="clickTrackHandler">
    <div
      ref="thumb"
      class="scrollbar__thumb"
      @mousedown="clickThumbHandler"
      :style="renderThumbStyle({ size, move, bar })"
    ></div>
  </div>
</template>
<script setup lang="ts">
import { computed, onUnmounted, getCurrentInstance, ref } from 'vue'
import { on, off } from '../../tools/dom'
import { renderThumbStyle, BAR_MAP } from './util'

defineOptions({
  name: 'cg-scrollbar-bar'
})

const $props = defineProps({
  vertical: Boolean,
  size: String,
  move: Number
})

const instance = getCurrentInstance()

const bar = computed(() => BAR_MAP[$props.vertical ? 'vertical' : 'horizontal'])

const wrap: any = computed(() => {
  const node = instance?.parent?.proxy as any
  return node['wrap']
})

const thumb = ref()

const root = ref()

const mapping: any = ref({})

const cursorDown = ref(false)

const clickThumbHandler = (e: any) => {
  if (e.ctrlKey || e.button === 2) {
    return
  }
  startDrag(e)
  mapping.value[bar.value.axis] =
    e.currentTarget[bar.value.offset] -
    (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction])
}

const clickTrackHandler = (e: any) => {
  if (typeof bar.value.offset === 'string') {
    const offset = Math.abs(
      e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]
    )

    const thumbHalf = thumb.value[bar.value.offset] / 2
    const thumbPositionPercentage = ((offset - thumbHalf) * 100) / root.value[bar.value.offset]
    wrap.value[bar.value.scroll] =
      (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100
  }
}

const startDrag = (e: any) => {
  e.stopImmediatePropagation()
  cursorDown.value = true
  on(document, 'mousemove', mouseMoveDocumentHandler)
  on(document, 'mouseup', mouseUpDocumentHandler)
  document.onselectstart = () => false
}

const mouseMoveDocumentHandler = (e: any) => {
  if (cursorDown.value === false) return
  const prevPage = mapping.value[bar.value.axis]
  if (!prevPage) return
  instance
  const offset =
    (root.value.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1
  const thumbClickPosition = thumb.value[bar.value.offset] - prevPage
  const thumbPositionPercentage =
    ((offset - thumbClickPosition) * 100) / root.value[bar.value.offset]

  wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100
}

const mouseUpDocumentHandler = () => {
  cursorDown.value = false
  mapping.value[bar.value.axis] = 0
  off(document, 'mousemove', mouseMoveDocumentHandler)
  document.onselectstart = null
}

onUnmounted(() => {
  off(document, 'mouseup', mouseUpDocumentHandler)
})
</script>
